package com.hotau.location;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;

/**
 * @author Cruise
 * @date 2011-12-16
 */
public class LocationUtil {
	private LocationManager locationManager;

	private LocationWrapper locationWrapper;

	private long timeout = 5 * 60 * 1000;

	private boolean isStarted;

	private static Object mutex = new Object();

	private SimpleLocationListener networkLocationListener;
	private SimpleLocationListener gpsLocationListener;

	class LocationWrapper {
		Location location;
		long time;
	}

	public Location getLastKnownLocation() {
		Location location = locationManager
				.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		if (location == null) {
			location = locationManager
					.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		}

		return location;
	}

	public Location requestLocation() {
		if (locationWrapper != null) {
			long timeOffset = System.currentTimeMillis() - locationWrapper.time;
			if (timeOffset <= timeout) {
				return locationWrapper.location;
			}
		}

		synchronized (mutex) {
			if (!isStarted) {
				this.startLocationMonitor();
			}

			try {
				mutex.wait(3 * 1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		return locationWrapper == null ? null : locationWrapper.location;

	}

	private LocationUtil(Context context) {
		locationManager = (LocationManager) context
				.getSystemService(Context.LOCATION_SERVICE);
	}

	static LocationUtil instance;

	public static LocationUtil getInstance(Context context) {
		if (instance == null) {
			synchronized (mutex) {
				if (instance == null) {
					instance = new LocationUtil(context);
				}
			}
		}

		return instance;
	}

	public void stopLocationMonitor() {
		if (this.isStarted) {
			if (networkLocationListener != null) {
				locationManager.removeUpdates(networkLocationListener);
				networkLocationListener = null;
			}

			if (gpsLocationListener != null) {
				locationManager.removeUpdates(gpsLocationListener);
				gpsLocationListener = null;
			}
		}
	}

	public void startLocationMonitor() {
		isStarted = true;

		String locationProvider = LocationManager.NETWORK_PROVIDER;
		if (locationManager.isProviderEnabled(locationProvider)) {
			if (networkLocationListener == null) {
				networkLocationListener = new SimpleLocationListener(
						locationProvider);
			}
			locationManager.requestLocationUpdates(locationProvider, 0, 0,
					networkLocationListener, Looper.getMainLooper());
		}

		locationProvider = LocationManager.GPS_PROVIDER;
		if (locationManager.isProviderEnabled(locationProvider)) {
			if (gpsLocationListener == null) {
				gpsLocationListener = new SimpleLocationListener(
						locationProvider);
			}
			locationManager.requestLocationUpdates(locationProvider, 0, 0,
					gpsLocationListener, Looper.getMainLooper());
		}
	}

	class SimpleLocationListener implements LocationListener {
		private String provider;

		public SimpleLocationListener(String provider) {
			this.provider = provider;
		}

		@Override
		public void onLocationChanged(Location location) {
			Log.d("mytag", "onLocationChanged: " + location + ", provider: " + provider);
			if (locationWrapper == null) {
				locationWrapper = new LocationWrapper();
			}

			locationWrapper.location = location;
			locationWrapper.time = System.currentTimeMillis();

			synchronized (mutex) {
				mutex.notifyAll();
			}
		}

		@Override
		public void onProviderDisabled(String provider) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onProviderEnabled(String provider) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub

		}

	}

}
